package com.cssl.config;

import cn.dev33.satoken.stp.StpInterface;
import cn.hutool.core.util.ObjUtil;
import com.cssl.domain.DtsPermission;
import com.cssl.domain.dto.DtsAdminDto;
import com.cssl.domain.dto.DtsAdminsDto;
import com.cssl.domain.dto.DtsPermissionDto;
import com.cssl.repository.AdminRepository;
import com.cssl.repository.PermissionRepository;
import com.cssl.repository.RoleRepository;
import com.cssl.util.ObjectMapperUtil;
import com.cssl.util.StorageVariable;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * 如果要使用redis存储 [账号id -> 角色id -> 权限列表]
 */
@Component
public class StpInterfaceImpl implements StpInterface {
    @Resource
    private StringRedisTemplate template;

    @Resource
    private ObjectMapperUtil util;
    @Resource
    private RoleRepository roleRepository;
    @Autowired
    private AdminRepository adminRepository;
    @Autowired
    private PermissionRepository permissionRepository;


    /**
     * 权限
     *
     * @param loginId
     * @param loginType
     * @return
     */
    @Override
    public List<String> getPermissionList(Object loginId, String loginType) {
        System.out.println("loginId = " + loginId);
        //先从redis中获取
        List<String> collect = new ArrayList<>();
        List<String> roleList = getRoleList(loginId, loginType);
        List<Integer> sss = roleList.stream()
                .map(s -> Integer.parseInt(s))
                .collect(Collectors.toList());


        for (Integer roleId : sss) {
            String s = template.opsForValue().get(StorageVariable.ADMIN_PERMISSION + ":" + loginId + ":" + roleId);
            if (s != null) {
                collect.addAll(util.fromJsonString(s, new TypeReference<List<String>>() {
                }));
            }
        }
        if (collect.size()==roleList.size()) {
            return collect;
        }
        List<DtsPermissionDto> allById = permissionRepository.findAllById(sss);
        Map<Integer, List<String>> permissionsByRoleId = allById.stream()
                .collect(Collectors.groupingBy(
                        DtsPermissionDto::getRoleId, // 分组依据是角色ID
                        Collectors.mapping(
                                DtsPermissionDto::getPermission, // 取出每个权限
                                Collectors.toList() // 收集到一个列表中
                        )
                ));
        Set<Map.Entry<Integer, List<String>>> entries = permissionsByRoleId.entrySet();
        for (Map.Entry<Integer, List<String>> entry : entries) {
            template.opsForValue().set(StorageVariable.ADMIN_PERMISSION + ":" + loginId + ":" + entry.getKey(), util.toJsonString(entry.getValue()), 7, TimeUnit.DAYS);
            collect.addAll(entry.getValue());
        }
        System.out.println("collect = " + collect);
        return collect;
    }

    /**
     * 角色
     * @param loginId
     * @param loginType
     * @return
     */
    @Override
    public List<String> getRoleList(Object loginId, String loginType) {
        List<String> roles = new ArrayList<>();
        //先从redis中获取角色
        String s = template.opsForValue().get(StorageVariable.ADMIN_ROLE + ":" + loginId);
        if (ObjUtil.isEmpty(s)) {
            Optional<DtsAdminsDto> byId1 = adminRepository.findById(Integer.parseInt(loginId.toString()));
            if (byId1.isPresent()) {
                String regex = "\\d+";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher(byId1.get().getRoleIds());
                List<Integer> result = new ArrayList<>();
                while (matcher.find()) {
                    result.add(Integer.parseInt(matcher.group()));
                }
                for (Integer id : result) {
                    roles.add(id + "");
                }
                template.opsForValue().set(StorageVariable.ADMIN_ROLE + ":" + loginId, util.toJsonString(roles), 7, TimeUnit.DAYS);
                return roles;
            }
        }
        roles = util.fromJsonString(s, new TypeReference<List<String>>() {
        });
        System.out.println("s = " + roles);
        return roles;
    }
}
